package com.sukumar.android.backit.db;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;

import com.sukumar.android.backit.db.BackItDBData.BackItRule;
import com.sukumar.android.backit.db.BackItDBData.BackItSMSInbox;

public class BackItDataAccessProvider extends ContentProvider {

	private static final String DATABASE_NAME = "BackItSms.db";
	private static final int DATABASE_VERSION = 2;
	private static final UriMatcher sUriMatcher;

	private static final int INBOX_MESSAGE = 1;
	private static final int RULE = 2;

	private static HashMap<String, String> InboxProjectionMap;
	private static HashMap<String, String> RuleProjectionMap;

	private static class DatabaseHelper extends SQLiteOpenHelper {

		DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE " + BackItDBData.INBOX_MESSAGE_TABLE_NAME
					+ " (" 
					+ BackItSMSInbox._ID + " INTEGER PRIMARY KEY,"
					+ BackItSMSInbox.BINGID + " TEXT,"
					+ BackItSMSInbox.RECEPIENT + " TEXT,"
					+ BackItSMSInbox.MESSAGE + " TEXT,"
					+ BackItSMSInbox._COUNT + " INTEGER,"
					+ BackItSMSInbox.DATE + " TEXT"
					+ ");");
			
			db.execSQL("CREATE TABLE " + BackItDBData.RULE_TABLE_NAME
					+ " (" 
					+ BackItRule._ID + " INTEGER PRIMARY KEY,"
					+ BackItRule.RULENAME + " TEXT,"
					+ BackItRule.PATTERN + " TEXT UNIQUE,"
					+ BackItRule.NOTIFURI + " TEXT,"
					+ BackItRule.VIBRATE + " INTEGER,"
					+ BackItRule.ENABLED + " TEXT,"
					+ BackItRule.REPEAT + " INTEGER"
					+ ");");
			
			db.execSQL("INSERT INTO "+ BackItDBData.RULE_TABLE_NAME 
					+" VALUES(1, \"BING\", \"BING\", \"\", \"Y\", \"Y\", -99);");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			db.execSQL("DROP TABLE IF EXISTS "
					+ BackItDBData.INBOX_MESSAGE_TABLE_NAME);
			db.execSQL("DROP TABLE IF EXISTS "
					+ BackItDBData.RULE_TABLE_NAME);
			onCreate(db);
		}
	}

	private DatabaseHelper dbHelper;

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) {
		case INBOX_MESSAGE:
			count = db.delete(BackItDBData.INBOX_MESSAGE_TABLE_NAME, where,
					whereArgs);
			break;
		case RULE:
			count = db.delete(BackItDBData.RULE_TABLE_NAME, where,
					whereArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch (sUriMatcher.match(uri)) {
		case INBOX_MESSAGE:
			return BackItDBData.CONTENT_TYPE;
		case RULE:
			return BackItDBData.CONTENT_TYPE;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {
		int uriMatch = sUriMatcher.match(uri);
		if (uriMatch != INBOX_MESSAGE && uriMatch != RULE) {
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		SQLiteDatabase db = dbHelper.getWritableDatabase();
		String tableName = null;
		Uri tableUri = null;
		switch (uriMatch) {
		case INBOX_MESSAGE: {
			tableName = BackItDBData.INBOX_MESSAGE_TABLE_NAME;
			tableUri = BackItSMSInbox.CONTENT_URI;
		}
			break;
		case RULE: {
			tableName = BackItDBData.RULE_TABLE_NAME;
			tableUri = BackItRule.CONTENT_URI;
		}
			break;
		default:
			break;
		}
		long rowId = db.insert(tableName, BaseColumns._ID, values);
		if (rowId > 0) {
			Uri noteUri = ContentUris.withAppendedId(tableUri, rowId);
			getContext().getContentResolver().notifyChange(noteUri, null);
			return noteUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

		switch (sUriMatcher.match(uri)) {
		case INBOX_MESSAGE:
			qb.setTables(BackItDBData.INBOX_MESSAGE_TABLE_NAME);
			qb.setProjectionMap(InboxProjectionMap);
			break;
		case RULE:
			qb.setTables(BackItDBData.RULE_TABLE_NAME);
			qb.setProjectionMap(RuleProjectionMap);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		SQLiteDatabase db = dbHelper.getWritableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null,
				null, sortOrder);

		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where,
			String[] whereArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) {
		case INBOX_MESSAGE:
			count = db.update(BackItDBData.INBOX_MESSAGE_TABLE_NAME, values,
					where, whereArgs);
			break;
		case RULE:
			count = db.update(BackItDBData.RULE_TABLE_NAME, values,
					where, whereArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(BackItDBData.AUTHORITY,
				BackItDBData.INBOX_MESSAGE_TABLE_NAME, INBOX_MESSAGE);
		sUriMatcher.addURI(BackItDBData.AUTHORITY,
				BackItDBData.RULE_TABLE_NAME, RULE);

		InboxProjectionMap = new HashMap<String, String>();
		InboxProjectionMap.put(BackItSMSInbox._ID, BackItSMSInbox._ID);
		InboxProjectionMap.put(BackItSMSInbox.BINGID, BackItSMSInbox.BINGID);
		InboxProjectionMap.put(BackItSMSInbox.RECEPIENT, BackItSMSInbox.RECEPIENT);
		InboxProjectionMap.put(BackItSMSInbox.MESSAGE, BackItSMSInbox.MESSAGE);
		InboxProjectionMap.put(BackItSMSInbox._COUNT, BackItSMSInbox._COUNT);
		InboxProjectionMap.put(BackItSMSInbox.DATE, BackItSMSInbox.DATE);
		
		RuleProjectionMap = new HashMap<String, String>();
		RuleProjectionMap.put(BackItRule._ID, BackItRule._ID);
		RuleProjectionMap.put(BackItRule.RULENAME, BackItRule.RULENAME);
		RuleProjectionMap.put(BackItRule.PATTERN, BackItRule.PATTERN);
		RuleProjectionMap.put(BackItRule.NOTIFURI, BackItRule.NOTIFURI);
		RuleProjectionMap.put(BackItRule.VIBRATE, BackItRule.VIBRATE);
		RuleProjectionMap.put(BackItRule.ENABLED, BackItRule.ENABLED);
		RuleProjectionMap.put(BackItRule.REPEAT, BackItRule.REPEAT);
		
	}

}
